#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define ENG 30
#define CN 50
#define LENGTH 8000

typedef struct word
{
    char eng[ENG];
    char cn[CN];
}word;
//更新单词
void updateWord(char* filePath, word* dic, int* length);
//删除单词
void deleteWord(char* filePath, word* dic, int* length);
//持久化操作 保存为txt
int saveDic(char* filePath, word* dic, int* length);
//添加单词
void addWord(char* filePath, word* dic, int* length);
//查找中文单词 大致意思
int searchCnWord(word* dic, int* length, char* targetWord);
//中文-》英文
void doCnToEng(word* dic, int* length);
//英文-》中文
void doEngToCn(word* dic, int* length);
//查找英文单词
int searchEngWord(word* dic, int* length, char* targetWord);
//执行相关操作
void excuteAction(char* filePath, word* dic, int* length, int action);
//提示界面
void printfAction();
//读取文件
int readFile(char* filePath, word* dic);
//插入排序
void insertSort(WORD *dic, int *length);
//冒泡排序
void bubbleSort(WORD *dic, int* length);

int main(){
    char* filePath = "D:\\dictionary.txt";
    int action = -1;
    int length = 0;
    int* pLength = &length;
    word dic[LENGTH];
    length = readFile(filePath, dic);
    /*for (int i = 0; i < length; i++)
    {
        printf("%s\t%s\n", dic[i].eng, dic[i].cn);
    }*/
    while (1)
    {
        printf("单词本有%d个单词\n", length);
        printfAction();
        scanf("%d", &action);
        excuteAction(filePath,dic, pLength, action);
    }

    return 0;
}

/**
 * 根据指令 执行相关的操作
 * @param filePath 文件路径
 * @param dic 词典数组
 * @param length 词典单词个数
 * @param action 指令代码
 */
void excuteAction(char* filePath, word* dic, int* length, int action){
    switch (action)
    {
        //退出
        case 0:{
            exit(0);
            break;
        }
            //根据输入的英文单词，查找中文意思
        case 1:{
            doEngToCn(dic,length);
            break;
        }
            //根据输入的中文单词，查找英文意思
        case 2:{
            doCnToEng(dic, length);
            break;
        }
            //添加单词
        case 3:{
            addWord(filePath,dic, length);
            break;
        }
            //删除单词
        case 4:{
            deleteWord(filePath, dic, length);
            break;
        }
            //修正单词
        case 5:{
            updateWord(filePath, dic, length);
            break;
        }
        default:
            printf("请输入0-5之间的数字！\n");
            break;
    }
}

/**
 * 更新单词
 * @param filePath 文件路径
 * @param dic 单词数组
 * @param length 词典中单词的个数
 */
void updateWord(char* filePath, word* dic, int* length){
    char eng[ENG];
    char cn[CN];
    int pos;//单词位置
    printf("请输入您要修正的单词：");
    scanf("%s", eng);
    pos = searchEngWord(dic,length,eng);
    if (pos != -1)
    {
        printf("请输入单词汉语翻译：");

        scanf("%s", cn);
        strcpy(dic[pos].cn, cn);
        saveDic(filePath, dic, length);
        printf("已经修正该单词翻译。\n");
    }
    else
        printf("对不起，没有找到您所需要的单词\n");
}

/**
 * 删除单词，如果词典中存在该单词就删除，不存在，则提示
 * @param filePath 文件路径
 * @param dic 单词数组
 * @param length 词典中单词的个数
 */
void deleteWord(char* filePath, word* dic, int* length){
    char eng[ENG];
    int pos = 0;
    printf("请输入您要删除的单词：");
    scanf("%s", eng);
    pos = searchEngWord(dic, length, eng);
    if (pos != -1){
        strcpy(dic[pos].eng, "#");
        strcpy(dic[pos].cn, "#");
        //删除单词之后，执行持久化操作，将数据保存为txt
        saveDic(filePath, dic, length);
        //单词个数减1
        (*length)--;
    }
    else
    {
        printf("您要删除的单词不存在!\n");
    }


}

/**
 * 添加单词，如果单词以及存在则提示，单词不存在，则进行添加操作
 * @param filePath 文件路径
 * @param dic 单词数组
 * @param length 词典中单词的个数
 */
void addWord(char* filePath, word* dic, int* length){
    word newWord;
    int pos = 0;
    printf("请输入您要添加的单词:");
    scanf("%s", newWord.eng);
    pos = searchEngWord(dic,length,newWord.eng);
    if(pos==-1){
        printf("请输入单词的中文意思:");
        scanf("%s", newWord.cn);
        strcpy(dic[*length].eng, newWord.eng);
        strcpy(dic[*length].cn, newWord.cn);
        (*length)++;
        saveDic(filePath,dic, length);
    } else{
        printf("该单词已经存在，不需要添加了！\n");
    }

}

/**
 * 持久化 将结构体数组中的单词保存到本地txt中
 * @param filePath 文件路径
 * @param dic 单词数组
 * @param length 词典中单词的个数
 * @return -1 文件保存失败，0 保存成功
 */
int saveDic(char* filePath, word* dic, int* length){
    int i = 0;
    FILE * fp = fopen(filePath, "w");
    if (fp == NULL){
        printf("文件保存失败\n");
        return -1;
    }
    //bubbleSort(dic,length);
    insertSort(dic,length);
    for (i = 0; i < *length; i++)
    {
        if (dic[i].eng[0] != '#'){
            if(i==((*length)-1)){
                fprintf(fp, "%s\t%s", dic[i].eng, dic[i].cn);
            }else{
                fprintf(fp, "%s\t%s\n", dic[i].eng, dic[i].cn);
            }
        }
    }
    fclose(fp);
    return 0;
}

/**
 * 根据中文查找英文翻译
 * @param dic 词典数组
 * @param length 词典中单词个数
 */
void doCnToEng(word* dic, int* length){
    char cn[CN];
    int pos=0;
    printf("请输入您要查询的中文单词(大致意思即可):");
    scanf("%s", cn);
    pos = searchCnWord(dic, length, cn);
    if (pos != -1){
        printf("\'%s\'的英文意思为：%s\n", cn, dic[pos].eng);
    }
    else
    {
        printf("对不起，没有找到您所需要的翻译\n");
    }
}

/**
 * 查询中文单词在词典中的位置
 * @param dic 词典数组
 * @param length 词典中的单词个数
 * @param targetWord 目标中文单词
 * @return 单词不存在返回-1，存在则返回单词在词典中的位置
 */
int searchCnWord(word* dic, int* length, char* targetWord){
    int i = 0;
    for (i = 0; i < *length; i++)
    {
        if (strstr(dic[i].cn, targetWord) != NULL){
            return i;
        }
    }
    return -1;
}


/**
 * 根据输入英文单词查找他的中文意思
 * @param dic 词典数组
 * @param length 词典中单词个数
 */
void doEngToCn(word* dic, int* length){
    char eng[ENG];
    int pos=0;
    printf("请输入您要查询的英文单词:");
    scanf("%s", eng);
    pos = searchEngWord(dic, length, eng);
    if (pos != -1){
        printf("您输入的单词\'%s\'中文意思为:%s\n", eng, dic[pos].cn);
    }
    else{
        printf("您输入的单词不存在\n");
    }
}
/**
 * 查找英文单词在数组中的位置
 * @param dic 词典数组
 * @param length 词典中单词个数
 * @param targetWord 目标英文单词
 * @return 如果单词存在则返回单词的位置，不存在则返回-1
 */
int searchEngWord(word* dic, int* length, char* targetWord){
    int low = 0, high = (*length) - 1;
    int mid = 0;
    int i = 0;
    while (low<=high)
    {
        mid = (low + high) / 2;
        if (strcmp(dic[mid].eng, targetWord)>0)
        {
            high = mid - 1;
        }
        else if (strcmp(dic[mid].eng, targetWord)<0)
        {
            low = low + 1;
        }
        else{
            return mid;
        }
    }
    //若二分查找查询不到，就执行顺序查找

    for (i = 0; i<*length; i++)
    {
        if (strcmp(dic[i].eng, targetWord) == 0)
            return i;
    }
    return -1;//如果查询不到，就返回负数
}

void printfAction(){
    printf("-----------------\n");
    printf("1.英译汉\t｜\n");
    printf("2.汉译英\t｜\n");
    printf("3.添加单词数据\t｜\n");
    printf("4.删除单词数据\t｜\n");
    printf("5.修正单词数据\t｜\n");
    printf("0.退出程序\t｜\n");
    printf("-----------------\n");
    printf("请输入您要执行的指令：");
}

/**
 * 读取词典txt文件
 * @param filePath 文件路径
 * @param dic 词典数组
 * @return
 */
int readFile(char* filePath, word* dic){
    char eng[30] = { 0 };
    char cn[50] = { 0 };
    int line = 0;

    FILE* fp = fopen(filePath, "r");
    if (fp == NULL){
        printf("文件打开失败，请检查您的文件\n");
        return -1;
    }

    while (!feof(fp))
    {
        fscanf(fp, "%s\t%s", dic[line].eng, dic[line].cn);
        line++;
        //printf("%s\t%s\n", eng, cn);

    }
    fclose(fp);
    return line;
}

/**
 * 冒泡排序
 * @param dic
 * @param length
 */
void bubbleSort(WORD *dic, int* length){
    WORD temp;
    int i=0, j=0;
    for(i=0;i<*length-1;i++){
        for(j=0;j<*length-i-1;j++){
            if(strcmp(dic[j].eng,dic[j+1].eng)>0){
                temp = dic[j];
                dic[j] = dic[j+1];
                dic[j+1] = temp;
            }
        }
    }
}

/**
 * 插入排序
 * @param dic
 * @param length
 */
void insertSort(WORD *dic, int *length){
    int i=0;
    WORD temp;
    for(i=*length-1;i>0;i--){
        if(strcmp(dic[i].eng,dic[i-1].eng)<0){
            temp = dic[i];
            dic[i] = dic[i-1];
            dic[i-1]=temp;
        }
    }
}